using System;
using System.Collections.Generic;
using System.Text;
using FlatRedBall;
using FlatRedBall.Input;
using FlatRedBall.AI.Pathfinding;
using FlatRedBall.Graphics.Animation;
using FlatRedBall.Graphics.Particle;

using FlatRedBall.Math.Geometry;
using FlatRedBall.Math.Splines;
using BitmapFont = FlatRedBall.Graphics.BitmapFont;
using Cursor = FlatRedBall.Gui.Cursor;
using GuiManager = FlatRedBall.Gui.GuiManager;
using Vector2 = Microsoft.Xna.Framework.Vector2;

using Microsoft.Devices.Sensors;

#if FRB_XNA || SILVERLIGHT
using Keys = Microsoft.Xna.Framework.Input.Keys;
using Vector3 = Microsoft.Xna.Framework.Vector3;
using Texture2D = Microsoft.Xna.Framework.Graphics.Texture2D;

using FlatRedBall.Instructions;
using NereusGame.Screens;
using NereusGame.Entities.Weapons;
using NereusGame.HUD;

#endif

namespace NereusGame.Entities.Ships
{
    // NOTE: I have used glue to create the Body -- the FRB cricle and Tex -- texture for player ship. This 2 variables are inherited from SHIP class
	public partial class Player
	{
        private const float CAMERA_Z = 100f;
        public PlayerHud hud;
        protected Xbox360GamePad gamePad1;    // Controller1
        protected Xbox360GamePad gamePad2;    // Controller2
        public Camera Cameras;              // Camera for the player
        public PauseScreen pauseMenu;
        public const int MAX_WEAPONS = 2;
        private const float MAX_HEALTH = 500f;      // Initial Health of the player.
        private const float MOVEMENT_SPEED = 30f;  // Initial MovementSpeed for the player
        private const float BODY_RADIUS = 2f;      // Initial Radius of the player
        private const float CAMERA_BOUNDS = 2f;    // boundry for the Camera to move with the player
        private const int MAX_DISTANCE = 300;
        private const int CUTOFF = 350;
        private Vector3 AccelerometerCalibrationData;

        private Accelerometer accel;

        private float movementSpeed;       // Movement speed of the player
        protected Sprite turret;             // Turret for the player.  

        private int score = 0;
        
     
        // Iitialize variables
		private void CustomInitialize()
		{
            InitializeControls();
            InitializePlayer();
            InitializeTurret();
            InitializeWepons();
            InitializePauseMenu();
            InitializeHud();
            hud.Update();
		}

		private void CustomActivity()
		{
            MovementActivity();
            RotateTurret();     // need help. Not working.
            CameraMovement();
            TogleWeapons();

		}

		private void CustomDestroy()
		{
            SpriteManager.RemoveSprite(turret);
            pauseMenu.Destroy();
            hud.Destroy();
            base.Destroy();
		}

        private static void CustomLoadStaticContent(string contentManagerName)
        {


        }


       

//*****************************************************INITIALIZE*****************************************************************//
        private void InitializeControls()
        {
            AccelerometerCalibrationData = GlobalContent.AccelerometerCalibrationData;
            if (accel == null)
            {
                accel = new Accelerometer();
                accel.Start();
            } 
            Drag = 5;
        }

        private void InitializePauseMenu()
        {
            pauseMenu = new PauseScreen(Cameras , gamePad1);

        }

        private void InitializeHud()
        {
            hud = new PlayerHud(Cameras, this);

        }
        // Initialize the turret
        private void InitializeTurret()
        {
            turret = new Sprite();
            turret.Texture = Turret;
            SpriteManager.AddSprite(turret);
            turret.AttachTo(Body, false);
            turret.ParentRotationChangesRotation = false;
            turret.ScaleX = BODY_RADIUS / 3f;
            turret.ScaleY = turret.ScaleX * 2;
            turret.RelativePosition.Y += 1f;

        }
        
        // Initialize the player
        private void InitializePlayer()
        {
            movementSpeed = MOVEMENT_SPEED;
            Cameras = SpriteManager.Camera;
            Cameras.Position.X = Position.X;
            Cameras.Position.Y = Position.Y;
            Cameras.Position.Z = CAMERA_Z;
            Drag = Cameras.Drag = FRICTION ;
            Tex.Texture = Ship;
            Body.Radius = Tex.ScaleX = Tex.ScaleY = BODY_RADIUS;
            state = ShipState.Alive;
            CurrentHealth = MaxHealth = MAX_HEALTH;
            Mass = 50;
        }

        // initialize Weapons
        private void InitializeWepons()
        {
            weaponInventory = new Weapon[MAX_WEAPONS];
            weaponInventory[0] = new Gun(CONTEN_MANAGER);
            weaponInventory[1] = new MissileLauncher(CONTEN_MANAGER);

            weaponInventory[0].UpgradeWeapon();    // set gun's level to 1
            weaponInventory[0].UpgradeWeapon();
            weaponInventory[0].UpgradeWeapon();
            weaponInventory[1].UpgradeWeapon();
            weaponInventory[1].UpgradeWeapon();// set missile's level to 1
            weaponInventory[1].UpgradeWeapon();
            weaponSelector = 1;
        }

        //*****************************************************CONTROL PLAYER SHIP*****************************************************************//
        // This function  accelerates  the player using the left thumstick or arrow keys: "Up, Down, Left, Right".
        protected  virtual void MovementActivity()
        { 
            // Control movement with the gamepad.
            Vector3 AdjustedAccelerometerData = Vector3.Zero;
            AdjustedAccelerometerData = accel.CurrentValue.Acceleration - AccelerometerCalibrationData;

            Acceleration.Y = AdjustedAccelerometerData.X * 100;
            Acceleration.X = AdjustedAccelerometerData.Y * -100;

            if (Acceleration.Length() < 6)
                Acceleration = Vector3.Zero;

            // Calculate direction towards the center of the system.
            Vector3 directionToStar = -Position;
            directionToStar.Normalize();

            // If the player is too far away, accelerate them back inside of the level's bounds.
            float distanceToStar = Position.Length();
            if (distanceToStar >= MAX_DISTANCE)
                Acceleration = directionToStar * 25 ;

            // Update the ship's rotation based on it's current angle of acceleration.
            RotationByAcceleration();
        }



        // This function is suppose to rotate the turret gradually in the direction the right stick is pointing towards
        protected void RotateTurret()
        {
                if (InputManager.TouchScreen.ScreenDown)
                {
                    float xinput = InputManager.TouchScreen.WorldXAt(0) - Position.X;
                    float yinput = InputManager.TouchScreen.WorldYAt(0) - Position.Y;

                    
                    turret.RelativeRotationZ = (float)((Math.Atan2(yinput, xinput) - (Math.PI * .5f)));
                    // shoting position needs to be computed here

                    Shoot();
                }

            #region Old Rotation Ccode
            /*
            if (SinglePlayerMode) // controller 1 control the turret
            {
                if (gamePad1.RightStick.Magnitude > 0)
                {       
 
                    if ( gamePad1.RightStick.Position.X < 0 )
                    {
                        turret.RelativeRotationZ += 0.02f;
                    }
                    else
                        turret.RelativeRotationZ -= 0.02f; 
                }
            }
            else // Controller 2 control the turret
            {
                if (gamePad2.RightStick.Magnitude > 0)
                {
                    if (gamePad2.RightStick.Position.X < 0)
                    {
                        turret.RelativeRotationZ += 0.02f;
                    }
                    elses
                        turret.RelativeRotationZ -= 0.02f;
                }
             */
            # endregion

        }

        // switch weapons when a player press button A
        protected void TogleWeapons()
        {
            if (Game1.mGameMode == Game1.GameMode.SinglePlayer)
            {
                if (InputManager.TouchScreen.DoubleTap)
                {
                    weaponSelector++;
                    if (weaponSelector > weaponInventory.Length -1)
                        weaponSelector = 0;                   
                }
            }
        }

//*****************************************************CAMERA MOVEMENT*****************************************************************//
        // moves the cammera deoending upon players movement.
        protected virtual void CameraMovement()
        {
            Cameras.Acceleration = (Position - Cameras.Position) * (Position - Cameras.Position).Length() * CAMERA_BOUNDS;
            Cameras.Acceleration.Z = 0;
            Cameras.Drag = 10;
        }

//*****************************************************Miscellaneous*****************************************************************//
        public override void Shoot()
        {

            // shoot the weapon
            if(weaponInventory[weaponSelector].Shoot(this,turret.Position, (BODY_RADIUS + 1f), turret.RelativeRotationZ, Velocity))
                weaponInventory[weaponSelector].playWeaponSound();

            // Math used to calculate shootign positon
            //Vector2 a = new Vector2(x1, y1);
            //Vector2 b = new Vector2(x2, y2);

            //Vector2 edge = b - a;
            //edge.Normalize();

            //Vector2 result = a + edge * d;

        }

        // This function sets the intial position of the player and the player camera.
        public void SetPlayerWithCamera(Vector3 pos)
        {
            Position = pos;
            Cameras.Position.X = pos.X;
            Cameras.Position.Y = pos.Y;
            Cameras.Position.Z = CAMERA_Z;
        }

        public void SetCamera(Camera c)
        {
            Cameras = c;
            //Cameras.AttachTo(this, false);
            Cameras.Position = Position;
            Cameras.Drag = FRICTION;
            Cameras.Position.Z = CAMERA_Z;
            pauseMenu.SetCamera(Cameras);
            hud.SetCamera(Cameras);
        }

        public int PlayerIndex
        {
            set
            {
                gamePad1 = InputManager.Xbox360GamePads[value];
                pauseMenu.SetGamePad(gamePad1);
            }
        }

        public int getScore()
        {
            return score;
        }

        public void increaseScore(int s)
        {
            score += s;
        }


        

	}
}


